import javax.swing.*;
import java.awt.*;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;

/**
 * DrawFace.java This class will draw the face of a sundial based on values
 * passed in
 * 
 * @author Arun Lee, Michael Terada, Marek Lopez
 * 
 */
public class DrawFace extends JFrame implements Printable {
	double[] hours;
	String[] stringHours;
	boolean southernHem = false; // If the user is in the southern hemisphere
	// Default is false, will change if not
	int length;
	double lat; // If latitude passed is negative, must print hours in reverse

	// default; should never execute
	public DrawFace() {
		this.hours = null;
		super.setTitle("Face Error");
		super.setSize(400, 400);
		super.setVisible(true);
		super.setBackground(Color.WHITE);
		super.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
	}

	public DrawFace(double[] hourLines, double latitude, int len) {
		Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
		this.hours = hourLines;
		this.lat = latitude;
		this.length = len;
		// check for negative latitude
		if (this.lat < 0) {
			this.southernHem = true;
		}
		// Set parameters of jFrame
		super.setTitle("Sundial Face");
		// frame.setSize(size);
		super.setSize(800, 800); // Edited Matt Kanda 10/28/2013 original
		// parameter
		// was size
		super.setVisible(true);
		super.setBackground(Color.WHITE);
		super.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		super.getContentPane().setBackground(Color.WHITE);
	}

	public void paint(Graphics canvas) {

		super.paintComponents(canvas); // Add by Matt Kanda 10/28/2013 Seems to
										// have fixed the problem

		if (hours == null) {
			// Should never execute; just error checking
			canvas.drawString("Hours array is null", 150, 200);
		} else {
			// Put the right hours in for printing
			stringHours = new String[] { "6", "7", "8", "9", "10", "11", "12",
					"1", "2", "3", "4", "5", "6" };
			int endX;
			int endY;
			int startBaseX = 25;
			int startBaseY = 400;
			int endBaseX = startBaseX + this.length * 2;
			int endBaseY = startBaseY;// Need base to be straight
			int middleBaseX = ((endBaseX - startBaseX) / 2) + startBaseX;
			int middleBaseY = startBaseY;
			int k = 0; // For iterating through the stringHour array

			canvas.setFont(new Font("TimesRoman", Font.PLAIN, 20));
			// baseline
			canvas.drawLine(startBaseX, startBaseY, endBaseX, endBaseY);
			// Check if hours need to be printed in reverse
			if (southernHem == true) {
				for (int i = 0; i < hours.length; i++) {
					if ((i % 2) == 0) {
						endX = (int) (middleBaseX - this.length
								* Math.sin(Math.toRadians(hours[i])));
						endY = (int) (middleBaseY - this.length
								* Math.cos(Math.toRadians(hours[i])));
						canvas.drawLine(middleBaseX, middleBaseY, endX, endY);
					} else {
						endX = (int) (middleBaseX - this.length / 2
								* Math.sin(Math.toRadians(hours[i])));
						endY = (int) (middleBaseY - this.length / 2
								* Math.cos(Math.toRadians(hours[i])));
						canvas.drawLine(middleBaseX, middleBaseY, endX, endY);
					}
					// Draw the hour numbers every other line
					if ((i % 2) == 0) {
						canvas.drawString(stringHours[k], endX, endY);
						k++;
					}
				}
				canvas.drawLine(middleBaseX, middleBaseY, middleBaseX,
						middleBaseY - this.length - 20);
				canvas.drawString("S", middleBaseX - this.length + 50,
						middleBaseY - this.length + 50);
				canvas.drawString("/\\", middleBaseX - this.length + 50,
						middleBaseY - this.length + 70);
			} else { // Not in southern hemisphere
				// Go through hours and draw a line for each degree
				for (int i = 0; i < hours.length; i++) {
					if ((i % 2) == 0) {
						endX = (int) (middleBaseX - this.length
								* Math.sin(Math.toRadians(-hours[i])));
						endY = (int) (middleBaseY - this.length
								* Math.cos(Math.toRadians(-hours[i])));
						canvas.drawLine(middleBaseX, middleBaseY, endX, endY);
					} else {
						endX = (int) (middleBaseX - this.length / 2
								* Math.sin(Math.toRadians(-hours[i])));
						endY = (int) (middleBaseY - this.length / 2
								* Math.cos(Math.toRadians(-hours[i])));
						canvas.drawLine(middleBaseX, middleBaseY, endX, endY);
					}
					// Draw the hour numbers every other line
					if ((i % 2) == 0) {
						canvas.drawString(stringHours[k], endX, endY);
						k++;
					}
				}
				canvas.drawLine(middleBaseX, middleBaseY, middleBaseX,
						middleBaseY - this.length - 20);
				canvas.drawString("N", middleBaseX - this.length + 50,
						middleBaseY - this.length + 50);
				canvas.drawString("/\\", middleBaseX - this.length + 50,
						middleBaseY - this.length + 70);

			}
		}
	}

	/**
	 * Required by Printable interface.
	 * 
	 * @param g
	 * @param pf
	 * @param page
	 * @return
	 * @throws PrinterException
	 */
	public int print(Graphics g, PageFormat pf, int page)
			throws PrinterException {
		// We have only one page, and 'page'
		// is zero-based
		if (page > 0) {
			return NO_SUCH_PAGE;
		}

		// User (0,0) is typically outside the
		// imageable area, so we must translate
		// by the X and Y values in the PageFormat
		// to avoid clipping.
		Graphics2D g2d = (Graphics2D) g;
		g2d.translate(pf.getImageableX(), pf.getImageableY());
		// Now we perform our rendering
		// This prints a grey page with the applet name at the top, but no
		// lines.
		// why no lines?
		this.paint(g2d);
		// tell the caller that this page is part
		// of the printed document
		return PAGE_EXISTS;
	}
}
